【SpringCloud Alibaba】Nacos服务管理与Feign负载均衡 | 您所在的位置:网站首页 › springcloud feign原理 › 【SpringCloud Alibaba】Nacos服务管理与Feign负载均衡 |
目录 一、微服务搭建 1.1 服务提供者与服务消费者 1.2 依赖关系
二、服务注册与负载均衡使用 2.1 Nacos 实现服务的注册与发现 2.2 Loadbalancer负载均衡、Feign声明式服务调用 2.3 示例综合实现 2.3.1 服务注册与发现测试 2.3.2 负载均衡测试 一、微服务搭建 1.1 服务提供者与服务消费者 服务提供者服务的被调用方(即:为其他微服务提供接口的微服务)服务消费者服务的调用方(即:调用其他微服务接口的微服务)就以图(仅供娱乐,无不良影响)为例搭建一个简单的微服务项目,可以看到一下项目结构: cloud (父级项目,这样为了更好管理项目资源): basketball (生产者) common (公共资源)ikun (消费者)1、Cloud顶级模块pom文件 (完整) : 4.0.0 org.example cloud 1.0-SNAPSHOT pom ikun basketball common 2.4.2 2020.0.1 2021.1 com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery ma.glasnost.orika orika-core 1.4.6 org.springframework.cloud spring-cloud-loadbalancer org.projectlombok lombok org.springframework.cloud spring-cloud-starter-openfeign org.springframework.boot spring-boot-dependencies ${spring-boot.version} pom import org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import com.alibaba.cloud spring-cloud-alibaba-dependencies ${spring-cloud-alibaba.version} pom import在父级中指定了子模块,子模块需要引用父级模块就能同步使用父级依赖,这样就可以把所有子模块共同依赖同意管理。 2、ikun子模块pom: (basketball如同) 4.0.0 com.example ikun 0.0.1-SNAPSHOT org.example cloud 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-web org.example common 1.0-SNAPSHOT org.apache.maven.plugins maven-compiler-plugin 3.8.1 1.8 1.8 UTF-8 org.springframework.boot spring-boot-maven-plugin ${spring-boot.version} com.example.ikun.IkunApplication repackage repackage二、服务注册与负载均衡使用 以上的操作只是建造了一个空壳,我们需要通过一些组件来继续完善微服务体系结构。 2.1 Nacos 实现服务的注册与发现Nacos下载:Releases · alibaba/nacos · GitHub 1、添加依赖 com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery2、配置服务提供者,从而服务提供者可以通过 Nacos 的服务注册发现功能将其服务注册到 Nacos server 上。 basketball(服务提供者)配置Nacos server 的地址: server: port: 8080 spring: cloud: nacos: server-addr: localhost:8848 application: name: basketball通过 Spring Cloud 原生注解 @EnableDiscoveryClient 开启服务注册发现功能: package com.example.basketball; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class BasketballApplication { public static void main(String[] args) { SpringApplication.run(BasketballApplication.class, args); } }3、配置服务消费者,从而服务消费者可以通过 Nacos 的服务注册发现功能从 Nacos server 上获取到它要调用的服务。 ikun(服务消费者)中配置 Nacos server 的地址: server: port: 8081 spring: cloud: nacos: server-addr: localhost:8848 application: name: ikun通上在启动类上添加 Spring Cloud 原生注解 @EnableDiscoveryClient 开启服务注册发现功能。 2.2 Loadbalancer负载均衡、Feign声明式服务调用因为两个子模块都需要此组件,所以直接在父模块cloud添加负载均衡依赖: org.springframework.cloud spring-cloud-loadbalancer org.springframework.cloud spring-cloud-starter-openfeign在两个子模块启动类添加注释开启服务通信 @EnableFeignClients 2.3 示例综合实现那么所有配置都已搭建好,接下来编写api接口来实现服务通信与负载均衡: 1、准备一个实体与dto类,因为本次示例并没有连接数据库,仅仅编写一个类用于实例化数据。这里我准备了一个公共模块(common)用来放置公共所需的类 package pojo.dto; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @author 云村小威 * @create 2024-01-06 15:52 */ @Data @NoArgsConstructor @AllArgsConstructor public class IkunDto { private Long id; private String account; private String password; private Integer age; private String hobby; }消费者 远程调用 生产者 : 需要网络传输,使用DTO同一封装对象 原理与SpringBoot启动类相同 将DTO对象封装到公共DTO模块为需要的项目引入公共DTO模块 org.example common 1.0-SNAPSHOT注意点: 不需要继承父模块(重复引用问题)打包方式为jar不需要添加启动类的编译VO(View Object):视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据 封装起来。 DTO(Data Transfer Object):数据传输对象,这个概念来源于J2EE的设计模式,原来的目的是 为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的 性能和降低网络负载,但在这里,我泛指用于展示层与服务层之间的数据传输对象。 DO(Domain Object):领域对象,就是从现实世界中抽象出来的有形或无形的业务实体。 PO(Persistent Object):持久化对象,它跟持久层(通常是关系型数据库)的数据结构形成一 一对应的映射关系,如果持久层是关系型数据库,那么,数据表中的每个字段(或若干个)就对应 PO的一个(或若干个)属性。 2、服务提供者(basketball) 提供接口方法和返回结果 package com.example.basketball.controller; import pojo.dto.IkunDto; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import java.util.Map; @Slf4j @RestController @RequestMapping("/kun") public class CXKController { @RequestMapping("/{account}") public String getByPath(@PathVariable String account) { log.info("account:" + account); return "kun : 唱"; } @RequestMapping("/param") public String getByParam(@RequestParam("account") String account, @RequestParam("password") String password) { log.info("param:" + account + "\t" + password); return "kun : 跳"; } @RequestMapping("/pojo") public String getByPojo(@RequestBody IkunDto ikunDto) { log.info("dto:" + ikunDto); return "kun : rep"; } @RequestMapping("/more") public String getByMore(@RequestBody Map map) { log.info("more:" + map); return "🏀"; } }3、服务消费者(ikun) I. 创建Server,并使用Feign表示其需要远程对接的服务名称,并使用@RequestMapping表示其映射的 路径 package com.example.ikun.serice; import pojo.dto.IkunDto; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import java.util.Map; /** * 连接生产者 Controller * * @author 云村小威 * @create 2024-01-06 15:40 */ @FeignClient("basketball") //连接服务器名称(服务提供者yml设置) @RequestMapping("/kun") public interface FeginKunService { @RequestMapping("/{account}") public String getByPath(@PathVariable(value = "account") String account); @RequestMapping("/param") public String getByParam(@RequestParam("account") String account, @RequestParam("password") String password); @RequestMapping("/pojo") public String getByPojo(@RequestBody IkunDto ikunDto); @RequestMapping("/more") public String getByMore(@RequestBody Map map); }II. 消费者行为接口测试 package com.example.ikun.controller; import com.example.ikun.serice.FeginKunService; import pojo.dto.IkunDto; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; @RestController public class TestController { @Autowired private FeginKunService kunService; @RequestMapping("/play01") public String play() { return kunService.getByPath("姬霓太美"); } @RequestMapping("/play02") public String play02() { return kunService.getByParam("小黑子", "123"); } @RequestMapping("/play03") public String play03() { return kunService.getByPojo(new IkunDto(1L, "纯路人", "123", 5 / 2, "music")); } @RequestMapping("/play04") public String play04() { Map paramMap = new HashMap(); paramMap.put("真爱粉", new IkunDto(2L, "梅丽猫", "321", 5 / 2, "唱、跳、rep、篮球")); return kunService.getByMore(paramMap); } }III. 先启动Nacos服务、在启动项目 这里注意Nacos默认为集群模式,本次示例并没有连接数据库,所以要修改为单机模式启动 windows指令 : startup.cmd -m standalone
接着输入nacos地址进行登录,账号与密码默认为:nacos 接着就可以看到已注册的服务 最后接口测试: 2.3.1 服务注册与发现测试Nacos服务注册与发现的流程: 1、服务注册: 在微服务启动时,它会向 Nacos 服务注册自己的信息,包括 IP 地址、端口号、服务名称等。通过 Nacos 的客户端 SDK 或与之集成的框架(如 Spring Cloud)来完成服务注册。2、服务发现: 当一个服务需要调用另一个服务时,它会向 Nacos 发送一个服务发现请求,请求特定服务名称的所有可用实例。Nacos 会返回该服务名称对应的所有服务实例信息,包括 IP 地址和端口号。调用方可以根据负载均衡策略选择一个实例进行调用,从而实现服务间的通信。 2.3.2 负载均衡测试为了更好体现负载均衡的作用,这里将basketball与ikun两个模块进行打包运行测试 Tip: 请看上面这张动图:首先我启用了两个生产者(basketball)和一个消费者(ikun),在ikun调用basketball方法时,它是实现了负载均衡的(各自权重都为1)。而我把一个basketball关掉之后,它并立刻没有把服务下线。原因是服务它会时刻会向Nacos发送心跳证明我还活着,如果关掉某个服务,Nacos会给服务10秒的等待时间,10秒内服务没有向Nacos发送心跳就会把他下线不在使用此服务。 |
CopyRight 2018-2019 实验室设备网 版权所有 |